package casts.misc
{
   import flash.display.Bitmap;
   import flash.display.BitmapData;
   import flash.display.MovieClip;
   import flash.events.Event;
   import flash.events.StatusEvent;
   import flash.events.TimerEvent;
   import flash.geom.Matrix;
   import flash.media.Camera;
   import flash.media.Video;
   import flash.utils.Timer;
   // greensock
   import com.greensock.TweenMax;

   /**
    * webcam容器範本：
    * 1. 影像大小就和該元件一樣大
    * @author cjboy | cjboy1984@gmail.com
    * @usage
      cam.startWebcam();
      cam.takeAShot();
      trace(cam.snapshot);

      cam.clearShot();
      cam.stopWebcam();
    */
   public class Webcam_1 extends MovieClip
   {
      // framerate of the camera.
      private const FRAME_RATE:Number = 20;
      // canvas bg-color
      private const BG_COLOR:uint = 0xffffff;

      // webcam width & height
      private var FIX_WIDTH:Number;
      private var FIX_HEIGHT:Number;

      // webcam
      private var cam:Camera;
      private var video:Video;
      // 顯示webcam影像的畫布，為了snapshot功能而做(可暫停/播放)
      private var capture:Bitmap;
      private var captureTimer:Timer;
      private var snaping:Boolean;
      // snapshot
      private var bmpData:BitmapData;

      public function Webcam_1()
      {
         stop();

         addEventListener(Event.ADDED_TO_STAGE, onAdd);
         addEventListener(Event.REMOVED_FROM_STAGE, onRemove);
      }

      // --------------------- LINE ---------------------

      public function startWebcam():void
      {
         // webcam
         cam = Camera.getCamera();
         cam.setMode(FIX_WIDTH, FIX_HEIGHT, FRAME_RATE);

         video = new Video(FIX_WIDTH, FIX_HEIGHT);
         video.attachCamera(cam);

         // 監聽使用者是否授權接受webcam影像
         cam.addEventListener(StatusEvent.STATUS, camStatUpdate);
         // 如果早就授權使用webcam，就直接開始
         if(!cam.muted) camStatUpdate();
      }

      public function stopWebcam():void
      {
         // webcam
         video.attachCamera(null);
         video = null;
         cam = null;
         cam.removeEventListener(StatusEvent.STATUS, camStatUpdate);

         // canvas
         if (capture)
         {
            TweenMax.killTweensOf(capture);
         }

         // render canvas
         if (captureTimer)
         {
            captureTimer.removeEventListener(TimerEvent.TIMER, render);
            captureTimer.stop();
            captureTimer = null;
         }
      }

      // --------------------- LINE ---------------------

      // 拍照
      public function takeAShot():void
      {
         if (!captureTimer) return;
         if (snaping) return;

         snaping = true;
         captureTimer.stop();
         bmpData = capture.bitmapData.clone();

         // 做閃光燈效果
         TweenMax.to(capture, 0, { colorTransform: { exposure:2 } } );
         TweenMax.to(capture, 1, { colorTransform: { exposure:1 }, onComplete:function() { snaping = false; } } );
      }

      // 照片資料
      public function get snapshot():BitmapData
      {
         return bmpData;
      }

      // 移掉拍照
      public function clearShot():void
      {
         if (!captureTimer) return;
         if (snaping) return;

         captureTimer.reset();
         captureTimer.start();
      }

      // ################### protected ##################

      // #################### private ###################

      private function onAdd(e:Event):void
      {
         FIX_WIDTH = width;
         FIX_HEIGHT = height;

         // webcam canvas
         capture = new Bitmap(new BitmapData(FIX_WIDTH, FIX_HEIGHT, false, BG_COLOR));
         addChild(capture);
         snaping = false;
      }

      private function onRemove(e:Event):void
      {
         // webcam canvas
         removeChild(capture);
         capture.bitmapData.dispose();
         capture = null;

         stopWebcam();
      }

      // --------------------- LINE ---------------------

      private function camStatUpdate(e:StatusEvent = null):void
      {
         if (!cam.muted)
         {
            // render canvas
            captureTimer = new Timer(1000 / FRAME_RATE);
            captureTimer.addEventListener(TimerEvent.TIMER, render);
            captureTimer.start();
         }
         else
         {
            MyAlert.jsShow('無法取得webcam影像！');

            if (captureTimer)
            {
               captureTimer.removeEventListener(TimerEvent.TIMER, render);
               captureTimer.stop();
               captureTimer = null;
            }
         }
      }

      private function render(e:TimerEvent):void
      {
         var mx:Matrix = new Matrix();
         // remove mirror effect
         mx.scale( -1, 1);
         mx.translate(FIX_WIDTH, 0);
         capture.bitmapData.draw(video, mx);
      }

      // --------------------- LINE ---------------------

   }

}